home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / typeface / source / gadget.c < prev    next >
C/C++ Source or Header  |  1996-05-04  |  29KB  |  1,109 lines

  1. /************************/
  2. /*            */
  3. /* Gadgets for Typeface */
  4. /*            */
  5. /************************/
  6.  
  7. #include "Typeface.h"
  8.  
  9. extern struct GfxBase *GfxBase;
  10.  
  11. /* For any gadget */
  12.  
  13. void Gadg_DrawBevel(struct RastPort *rp,ULONG x,ULONG y,ULONG w,ULONG h,
  14.   UBYTE pen1,UBYTE pen2)
  15. {
  16.   SetAPen(rp,pen1);
  17.   Move(rp,x+w-2,y);
  18.   Draw(rp,x,y);
  19.   Draw(rp,x,y+h-1);
  20.   Move(rp,1+x,y+h-2);
  21.   Draw(rp,1+x,1+y);
  22.  
  23.   SetAPen(rp,pen2);
  24.   Move(rp,1+x,y+h-1);
  25.   Draw(rp,x+w-1,y+h-1);
  26.   Draw(rp,x+w-1,y);
  27.   Move(rp,x+w-2,1+y);
  28.   Draw(rp,x+w-2,y+h-2);
  29. }
  30.  
  31. void Gadg_SetTag(struct TagItem *tag,ULONG id, ULONG data)
  32. {
  33.   tag->ti_Tag = id;
  34.   tag->ti_Data = data;
  35. }
  36.  
  37. /* character selection gadget */
  38.  
  39. #define CG_XOFFSET 6
  40. #define CG_YOFFSET 3
  41.  
  42. struct CharGadgData
  43. {
  44.   UWORD cg_CharWidth,cg_CharHeight;
  45.   WORD cg_FirstX,cg_FirstY;
  46.   struct TextFont *cg_TextFont;
  47.   ULONG cg_LastPressed,cg_Pos;
  48.   BOOL cg_Pressed,cg_Redraw;
  49.   UWORD cg_SizeX,cg_SizeY;
  50.   ULONG cg_ShiftPressed;
  51. };
  52.  
  53. __geta4 ULONG DispatchCharGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  54. ULONG CharGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  55. ULONG CharGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr);
  56. ULONG CharGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi);
  57. ULONG CharGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  58.   struct gpInput *gpi);
  59. ULONG CharGadg_GOINACTIVE(Class *cl,struct Gadget *gadg,
  60.   struct gpGoInactive *gpgi);
  61. ULONG CharGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops);
  62. ULONG CharGadg_GET(Class *cl,Object *o,struct opGet *opg);
  63. void CharGadg_DrawChar(struct RastPort *rp,struct GadgetInfo *gi,
  64.   BOOL selected,ULONG x,ULONG y,ULONG w,ULONG h,char gchar,BOOL lines);
  65. void CharGadg_DrawCurrent(struct GadgetInfo *gi,struct CharGadgData *cgd,
  66.   struct Gadget *gadg);
  67.  
  68. Class *InitCharGadgClass(void)
  69. {
  70. Class *super, *cl = NULL;
  71.  
  72.   if (super = BGUI_GetClassPtr(BGUI_BASE_GADGET))
  73.   {
  74.     cl = MakeClass(NULL,NULL,super,sizeof(struct CharGadgData),0);
  75.     if (cl) cl->cl_Dispatcher.h_Entry = (HOOKFUNC)DispatchCharGadg;
  76.   }
  77.   return cl;
  78. }
  79.  
  80. BOOL FreeCharGadgClass(Class *cl)
  81. {
  82.   return FreeClass(cl);
  83. }
  84.  
  85. ULONG GetCharGadgWidth(UWORD width,struct TextFont *font)
  86. {
  87. struct TextFont *gadget_font;
  88.  
  89.   gadget_font = font ? font : GfxBase->DefaultFont;
  90.   return (gadget_font->tf_XSize+(CG_XOFFSET*2))*width;
  91. }
  92.  
  93. ULONG GetCharGadgHeight(UWORD height,struct TextFont *font)
  94. {
  95. struct TextFont *gadget_font;
  96.  
  97.   gadget_font = font ? font : GfxBase->DefaultFont;
  98.   return (gadget_font->tf_YSize+(CG_YOFFSET*2))*height;
  99. }
  100.  
  101. __geta4 ULONG DispatchCharGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  102. {
  103. ULONG retval;
  104.  
  105.   switch (msg->MethodID)
  106.   {
  107.     case OM_NEW:
  108.       retval = CharGadg_NEW(cl,o,(struct opSet *)msg);
  109.       break;
  110.     case OM_SET:
  111.       retval = CharGadg_SET(cl,(struct Gadget *)o,(struct opSet *)msg);
  112.       break;
  113.     case OM_GET:
  114.       retval = CharGadg_GET(cl,o,(struct opGet *)msg);
  115.       break;
  116.     case GM_RENDER:
  117.       retval = CharGadg_RENDER(cl,(struct Gadget *)o,(struct gpRender *)msg);
  118.       break;
  119.     case GM_GOACTIVE:
  120.       retval = CharGadg_GOACTIVE(cl,(struct Gadget *)o,
  121.     (struct gpInput *)msg);
  122.       break;
  123.     case GM_HANDLEINPUT:
  124.       retval = CharGadg_HANDLEINPUT(cl,(struct Gadget *)o,
  125.     (struct gpInput *)msg);
  126.       break;
  127.     case GM_GOINACTIVE:
  128.       retval = CharGadg_GOINACTIVE(cl,(struct Gadget *)o,
  129.     (struct gpGoInactive *)msg);
  130.       break;
  131.     default:
  132.       retval = DoSuperMethodA(cl,o,(Msg)msg);
  133.       break;
  134.   }
  135.   return retval;
  136. }
  137.  
  138. ULONG CharGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  139. {
  140. ULONG retval = 0;
  141. struct CharGadgData *cgd;
  142.  
  143.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg)ops);
  144.   if (retval)
  145.   {
  146.     cgd = INST_DATA(cl,retval);
  147.     cgd->cg_TextFont = (struct TextFont *)
  148.       GetTagData(CG_Font,(ULONG)GfxBase->DefaultFont,ops->ops_AttrList);
  149.     cgd->cg_CharWidth = cgd->cg_TextFont->tf_XSize+(CG_XOFFSET*2);
  150.     cgd->cg_CharHeight = cgd->cg_TextFont->tf_YSize+(CG_YOFFSET*2);
  151.     cgd->cg_Pressed = FALSE;
  152.     cgd->cg_Redraw = TRUE;
  153.     cgd->cg_LastPressed = ~0;
  154.     cgd->cg_SizeX = GetTagData(CG_SizeX,8,ops->ops_AttrList);
  155.     cgd->cg_SizeY = GetTagData(CG_SizeY,8,ops->ops_AttrList);
  156.   }
  157.   return retval;
  158. }
  159.  
  160. ULONG CharGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr)
  161. {
  162. struct RastPort *rp;
  163. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  164. struct TextFont *old_tf = NULL;
  165. UWORD i,j;
  166.  
  167.   if (cgd->cg_Redraw == FALSE) return 0;
  168.   cgd->cg_Redraw = FALSE;
  169.  
  170.   rp = gpr->gpr_RPort;
  171.   if (rp->Font != cgd->cg_TextFont)
  172.   {
  173.     old_tf = rp->Font;
  174.     SetFont(rp,cgd->cg_TextFont);
  175.   }
  176.   if ((gpr->gpr_Redraw==GREDRAW_REDRAW)||(gpr->gpr_Redraw==GREDRAW_UPDATE))
  177.   {
  178.     for (i = 0; i < cgd->cg_SizeY; i++)
  179.     {
  180.       for (j = 0; j < cgd->cg_SizeX; j++)
  181.     CharGadg_DrawChar(rp,gpr->gpr_GInfo,FALSE,
  182.       (j*cgd->cg_CharWidth)+gadg->LeftEdge,
  183.       (i*cgd->cg_CharHeight)+gadg->TopEdge,
  184.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  185.       ((cgd->cg_Pos+i)*cgd->cg_SizeX)+j,
  186.       gpr->gpr_Redraw == GREDRAW_REDRAW);
  187.     }
  188.   }
  189.   if (old_tf) SetFont(rp,old_tf);
  190.   return 0;
  191. }
  192.  
  193. ULONG CharGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  194. {
  195. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  196. struct GadgetInfo *gi;
  197. WORD i,j;
  198. ULONG retval = GMR_NOREUSE;
  199.  
  200.   DoSuperMethodA(cl,(Object *)gadg,(Msg)gpi);
  201.   cgd->cg_FirstX = -1; cgd->cg_FirstY = -1; cgd->cg_Pressed = TRUE;
  202.   j = gpi->gpi_Mouse.X / cgd->cg_CharWidth;
  203.   i = gpi->gpi_Mouse.Y / cgd->cg_CharHeight;
  204.   if ((i >= 0) && (i < cgd->cg_SizeY) && (j >= 0) && (j < cgd->cg_SizeX))
  205.   {
  206.     cgd->cg_FirstX = j; cgd->cg_FirstY = i;
  207.     gi = gpi->gpi_GInfo;
  208.     CharGadg_DrawCurrent(gi,cgd,gadg);
  209.     retval = GMR_MEACTIVE;
  210.   }
  211.   return retval;
  212. }
  213.  
  214. ULONG CharGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  215. {
  216. struct GadgetInfo *gi = gpi->gpi_GInfo;
  217. struct InputEvent *ie = gpi->gpi_IEvent;
  218. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  219. ULONG retval = GMR_MEACTIVE;
  220. WORD i,j;
  221.  
  222.   if (gi->gi_Window)
  223.   {
  224.     if ((gi->gi_Window->Flags & WFLG_WINDOWACTIVE) == 0) return GMR_NOREUSE;
  225.   }
  226.   while (ie && (retval == GMR_MEACTIVE))
  227.   {
  228.     if (ie->ie_Class == IECLASS_RAWMOUSE)
  229.     {
  230.       if (ie->ie_Code != SELECTUP)
  231.       {
  232.     cgd->cg_ShiftPressed =
  233.       ie->ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT);
  234.     j = gpi->gpi_Mouse.X / cgd->cg_CharWidth;
  235.     i = gpi->gpi_Mouse.Y / cgd->cg_CharHeight;
  236.     if ((i == cgd->cg_FirstY) && (j == cgd->cg_FirstX))
  237.     {
  238.       if (cgd->cg_Pressed == FALSE)
  239.       {
  240.         cgd->cg_Pressed = TRUE;
  241.         CharGadg_DrawCurrent(gi,cgd,gadg);
  242.       }
  243.     }
  244.     else
  245.     {
  246.       if (cgd->cg_Pressed == TRUE)
  247.       {
  248.         cgd->cg_Pressed = FALSE;
  249.         CharGadg_DrawCurrent(gi,cgd,gadg);
  250.       }
  251.     }
  252.       }
  253.       else retval = GMR_NOREUSE|GMR_VERIFY;
  254.     }
  255.     ie = ie->ie_NextEvent;
  256.   }
  257.   return retval;
  258. }
  259.  
  260. ULONG CharGadg_GOINACTIVE(Class *cl,struct Gadget *gadg,
  261.   struct gpGoInactive *gpgi)
  262. {
  263. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  264. struct GadgetInfo *gi;
  265. struct RastPort *rp;
  266. struct TextFont *old_tf = NULL;
  267. struct TagItem inactive;
  268. ULONG retval;
  269.  
  270.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg)gpgi);
  271.   if ((cgd->cg_FirstX != -1) && (cgd->cg_FirstY != -1))
  272.   {
  273.     gi = gpgi->gpgi_GInfo;
  274.     if (cgd->cg_Pressed == TRUE)
  275.     {
  276.       if (rp = ObtainGIRPort(gi))
  277.       {
  278.     if (rp->Font != cgd->cg_TextFont)
  279.     {
  280.       old_tf = rp->Font;
  281.       SetFont(rp,cgd->cg_TextFont);
  282.     }
  283.     CharGadg_DrawChar(rp,gi,FALSE,
  284.       (cgd->cg_FirstX*cgd->cg_CharWidth)+gadg->LeftEdge,
  285.       (cgd->cg_FirstY*cgd->cg_CharHeight)+gadg->TopEdge,
  286.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  287.       ((cgd->cg_Pos+cgd->cg_FirstY)*cgd->cg_SizeX)+cgd->cg_FirstX,
  288.       TRUE);
  289.     if (old_tf) SetFont(rp,old_tf);
  290.     ReleaseGIRPort(rp);
  291.       }
  292.       cgd->cg_LastPressed =
  293.     ((cgd->cg_Pos+cgd->cg_FirstY)*cgd->cg_SizeX)+cgd->cg_FirstX;
  294.       Gadg_SetTag(&inactive,TAG_DONE,0);
  295.       DoMethod((Object *)gadg,OM_NOTIFY,&inactive,gi,0);
  296.     }
  297.   }
  298.   return retval;
  299. }
  300.  
  301. ULONG CharGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops)
  302. {
  303. struct TagItem *tags, *tag;
  304. ULONG retval;
  305. struct CharGadgData *cgd = INST_DATA(cl,(Object *)gadg);
  306. struct RastPort *rp;
  307.  
  308.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg)ops);
  309.   tags = ops->ops_AttrList;
  310.   if (tags)
  311.   {
  312.     if (tag = FindTagItem(CG_Pos,tags))
  313.     {
  314.       if (cgd->cg_Pos != tag->ti_Data) cgd->cg_Pos = tag->ti_Data;
  315.     }
  316.     if (tag = FindTagItem(CG_SizeY,tags))
  317.     {
  318.       if (cgd->cg_SizeY != tag->ti_Data) cgd->cg_SizeY = tag->ti_Data;
  319.     }
  320.     if (tag = FindTagItem(CG_Redraw,tags))
  321.     {
  322.       if (rp = ObtainGIRPort(ops->ops_GInfo))
  323.       {
  324.     cgd->cg_Redraw = TRUE;
  325.     DoMethod((Object *)gadg,GM_RENDER,ops->ops_GInfo,rp,
  326.       tag->ti_Data ? GREDRAW_REDRAW : GREDRAW_UPDATE);
  327.     ReleaseGIRPort(rp);
  328.       }
  329.     }
  330.     if (tag = FindTagItem(CG_Pressed,tags))
  331.       cgd->cg_LastPressed = tag->ti_Data;
  332.   }
  333.   return retval;
  334. }
  335.  
  336. ULONG CharGadg_GET(Class *cl,Object *o,struct opGet *opg)
  337. {
  338. struct CharGadgData *cgd = INST_DATA(cl,o);
  339. ULONG retval = TRUE;
  340.  
  341.   switch (opg->opg_AttrID)
  342.   {
  343.     case CG_Pos:
  344.       *(opg->opg_Storage) = cgd->cg_Pos;
  345.       break;
  346.     case CG_Pressed:
  347.       *(opg->opg_Storage) = cgd->cg_LastPressed;
  348.       break;
  349.     case CG_SizeY:
  350.       *(opg->opg_Storage) = cgd->cg_SizeY;
  351.       break;
  352.     case CG_ShiftDown:
  353.       *(opg->opg_Storage) = cgd->cg_ShiftPressed;
  354.       break;
  355.     default:
  356.       retval = DoSuperMethodA(cl,o,(Msg)opg);
  357.       break;
  358.   }
  359.   return retval;
  360. }
  361.  
  362. void CharGadg_DrawChar(struct RastPort *rp,struct GadgetInfo *gi,
  363.   BOOL selected,ULONG x,ULONG y,ULONG w,ULONG h,char gchar, BOOL lines)
  364. {
  365. struct DrawInfo *dri = gi->gi_DrInfo;
  366. UBYTE pen1,pen2,pen3,pen4;
  367.  
  368.   if (selected)
  369.   {
  370.     pen1 = dri->dri_Pens[SHADOWPEN];
  371.     pen2 = dri->dri_Pens[SHINEPEN];
  372.     pen3 = dri->dri_Pens[FILLTEXTPEN];
  373.     pen4 = dri->dri_Pens[FILLPEN];
  374.   }
  375.   else
  376.   {
  377.     pen1 = dri->dri_Pens[SHINEPEN];
  378.     pen2 = dri->dri_Pens[SHADOWPEN];
  379.     pen3 = dri->dri_Pens[TEXTPEN];
  380.     pen4 = dri->dri_Pens[BACKGROUNDPEN];
  381.   }
  382.   SetAPen(rp,pen4);
  383.   if (lines)
  384.   {
  385.     RectFill(rp,x,y,x+w-1,y+h-1);
  386.     Gadg_DrawBevel(rp,x,y,w,h,pen1,pen2);
  387.   }
  388.   else RectFill(rp,x+2,y+1,x+w-5,y+h-3);
  389.   SetAPen(rp,pen3);
  390.   SetBPen(rp,pen4);
  391.   SetDrMd(rp,JAM2);
  392.   Move(rp,x+CG_XOFFSET,y+CG_YOFFSET+rp->Font->tf_Baseline);
  393.   Text(rp,&gchar,1);
  394. }
  395.  
  396. void CharGadg_DrawCurrent(struct GadgetInfo *gi,struct CharGadgData *cgd,
  397.   struct Gadget *gadg)
  398. {
  399. struct RastPort *rp;
  400. struct TextFont *old_tf = NULL;
  401.  
  402.   if (rp = ObtainGIRPort(gi))
  403.   {
  404.     if (rp->Font != cgd->cg_TextFont)
  405.     {
  406.       old_tf = rp->Font;
  407.       SetFont(rp,cgd->cg_TextFont);
  408.     }
  409.     CharGadg_DrawChar(rp,gi,cgd->cg_Pressed,
  410.       (cgd->cg_FirstX*cgd->cg_CharWidth)+gadg->LeftEdge,
  411.       (cgd->cg_FirstY*cgd->cg_CharHeight)+gadg->TopEdge,
  412.       cgd->cg_CharWidth,cgd->cg_CharHeight,
  413.       ((cgd->cg_Pos+cgd->cg_FirstY)*cgd->cg_SizeX)+cgd->cg_FirstX,TRUE);
  414.     if (old_tf) SetFont(rp,old_tf);
  415.     ReleaseGIRPort(rp);
  416.   }
  417. }
  418.  
  419. /* character editing gadget */
  420.  
  421. struct EditGadgData
  422. {
  423.   UWORD eg_PixelX,eg_PixelY;
  424.   struct Character *eg_Char;
  425.   UWORD eg_XOffset,eg_YOffset;
  426.   struct CharNode *eg_Node;
  427.   UWORD eg_Button, eg_PixelBorder, eg_ShowBaseline;
  428.   ULONG eg_Baseline;
  429.   BOOL *eg_ChangePtr;
  430.   WORD eg_ActiveX, eg_ActiveY;
  431.   UWORD eg_Toggle, eg_FirstPixelState;
  432. };
  433.  
  434. __geta4 ULONG DispatchEditGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  435. ULONG EditGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  436. ULONG EditGadg_GET(Class *cl,Object *o,struct opGet *opg);
  437. ULONG EditGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops);
  438. ULONG EditGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr);
  439. ULONG EditGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi);
  440. ULONG EditGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  441.   struct gpInput *gpi);
  442. void EditGadg_TogglePixel(struct Gadget *gadg,struct gpInput *gpi,
  443.   struct EditGadgData *egd,WORD i,WORD j,BOOL first);
  444.  
  445. Class *InitEditGadgClass(void)
  446. {
  447. Class *super, *cl = NULL;
  448.  
  449.   if (super = BGUI_GetClassPtr(BGUI_BASE_GADGET))
  450.   {
  451.     cl = MakeClass(NULL,NULL,super,sizeof(struct EditGadgData),0);
  452.     if (cl) cl->cl_Dispatcher.h_Entry = (HOOKFUNC)DispatchEditGadg;
  453.   }
  454.   return cl;
  455. }
  456.  
  457. BOOL FreeEditGadgClass(Class *cl)
  458. {
  459.   return FreeClass(cl);
  460. }
  461.  
  462. void EditGadg_GetSize(struct EditGadgData *egd,UWORD w,UWORD h,
  463.   UWORD *ew_ptr, UWORD *eh_ptr)
  464. {
  465. struct Character *chr;
  466.  
  467.   *ew_ptr = (w-(2*EG_XOFFSET))/(egd->eg_PixelX);
  468.   *eh_ptr = (h-(2*EG_YOFFSET))/(egd->eg_PixelY);
  469.   if (chr = egd->eg_Char)
  470.   {
  471.     if (*ew_ptr > chr->chr_Width) *ew_ptr = chr->chr_Width;
  472.     if (*eh_ptr > chr->chr_Height) *eh_ptr = chr->chr_Height;
  473.   }
  474. }
  475.  
  476. void EditGadg_Draw(Object *o, struct GadgetInfo *gi,ULONG draw)
  477. {
  478. struct RastPort *rp;
  479.  
  480.   if (rp = ObtainGIRPort(gi))
  481.   {
  482.     DoMethod(o,GM_RENDER,gi,rp,draw);
  483.     ReleaseGIRPort(rp);
  484.   }
  485. }
  486.  
  487. __geta4 ULONG DispatchEditGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  488. {
  489. ULONG retval;
  490.  
  491.   switch (msg->MethodID)
  492.   {
  493.     case OM_NEW:
  494.       retval = EditGadg_NEW(cl,o,(struct opSet *)msg);
  495.       break;
  496.     case OM_GET:
  497.       retval = EditGadg_GET(cl,o,(struct opGet *)msg);
  498.       break;
  499.     case OM_SET:
  500.     case OM_UPDATE:
  501.       retval = EditGadg_SET(cl,(struct Gadget *)o,(struct opSet *)msg);
  502.       break;
  503.     case GM_RENDER:
  504.       retval = EditGadg_RENDER(cl,(struct Gadget *)o,(struct gpRender *)msg);
  505.       break;
  506.     case GM_GOACTIVE:
  507.       retval = EditGadg_GOACTIVE(cl,(struct Gadget *)o,
  508.     (struct gpInput *)msg);
  509.       break;
  510.     case GM_HANDLEINPUT:
  511.       retval = EditGadg_HANDLEINPUT(cl,(struct Gadget *)o,
  512.     (struct gpInput *)msg);
  513.       break;
  514.     default:
  515.       retval = DoSuperMethodA(cl,o,(Msg)msg);
  516.       break;
  517.   }
  518.   return retval;
  519. }
  520.  
  521. ULONG EditGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  522. {
  523. ULONG retval = 0;
  524. struct EditGadgData *egd;
  525.  
  526.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg)ops);
  527.   if (retval)
  528.   {
  529.     egd = INST_DATA(cl,retval);
  530.     egd->eg_PixelX = GetTagData(EG_PixelX,32,ops->ops_AttrList);
  531.     egd->eg_PixelY = GetTagData(EG_PixelY,16,ops->ops_AttrList);
  532.     egd->eg_Char = (struct Character *)
  533.       GetTagData(EG_CharStruct,0,ops->ops_AttrList);
  534.     egd->eg_XOffset = 0;
  535.     egd->eg_YOffset = 0;
  536.     egd->eg_Node = (struct CharNode *)
  537.       GetTagData(EG_CharNode,0,ops->ops_AttrList);
  538.     egd->eg_Button = 0;
  539.     egd->eg_PixelBorder = GetTagData(EG_PixelBorder,1,ops->ops_AttrList);
  540.     egd->eg_ShowBaseline = GetTagData(EG_ShowBaseline,0,ops->ops_AttrList);
  541.     egd->eg_Toggle = GetTagData(EG_Toggle,0,ops->ops_AttrList);
  542.     egd->eg_Baseline = GetTagData(EG_Baseline,0,ops->ops_AttrList);
  543.     egd->eg_ChangePtr = (BOOL *)GetTagData(EG_ChangePtr,0,ops->ops_AttrList);
  544.   }
  545.   return retval;
  546. }
  547.  
  548. ULONG EditGadg_RENDER(Class *cl,struct Gadget *gadg,struct gpRender *gpr)
  549. {
  550. struct RastPort *rp;
  551. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  552. struct DrawInfo *dri = gpr->gpr_GInfo->gi_DrInfo;
  553. struct Character *chr;
  554. UBYTE pen1,pen2,pen3,pen4;
  555. UWORD ew,eh,i,j,x,y,w,h,p;
  556.  
  557.   rp = gpr->gpr_RPort;
  558.   if ((gpr->gpr_Redraw==GREDRAW_REDRAW)||(gpr->gpr_Redraw==GREDRAW_UPDATE))
  559.   {
  560.     if ((chr = egd->eg_Char) == NULL) return 0;
  561.     pen1 = dri->dri_Pens[SHINEPEN];
  562.     pen2 = dri->dri_Pens[SHADOWPEN];
  563.     pen3 = dri->dri_Pens[BACKGROUNDPEN];
  564.     pen4 = dri->dri_Pens[FILLPEN];
  565.     SetAfPt(rp,NULL,0);
  566.     x = gadg->LeftEdge; y = gadg->TopEdge;
  567.     w = gadg->Width; h = gadg->Height;
  568.     if (gpr->gpr_Redraw == GREDRAW_REDRAW)
  569.     {
  570.       SetAPen(rp,pen3);
  571.       RectFill(rp,x,y,x+w-1,y+h-1);
  572.     }
  573.     EditGadg_GetSize(egd,w,h,&ew,&eh);
  574.     w = (ew*(egd->eg_PixelX))+(2*EG_XOFFSET);
  575.     h = (eh*(egd->eg_PixelY))+(2*EG_YOFFSET);
  576.     p = (egd->eg_PixelBorder != 0) ? 2 : 1;
  577.     Gadg_DrawBevel(rp,x,y,w,h,pen1,pen2);
  578.     if (egd->eg_PixelBorder > 0)
  579.     {
  580.       SetAPen(rp,egd->eg_PixelBorder == 2 ? pen4 : pen3);
  581.       for (j = 0; j < eh-1; j++)
  582.       {
  583.     Move(rp,x+EG_XOFFSET,((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-1);
  584.     Draw(rp,x+w-EG_XOFFSET-1,((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-1);
  585.       }
  586.       SetAPen(rp,pen3);
  587.       Move(rp,x+EG_XOFFSET,(eh*egd->eg_PixelY)+y+EG_YOFFSET-1);
  588.       Draw(rp,x+w-EG_XOFFSET-1,(eh*egd->eg_PixelY)+y+EG_YOFFSET-1);
  589.     }
  590.     if (egd->eg_PixelBorder == 2)
  591.     {
  592.       SetAPen(rp,pen4);
  593.       for (i = 0; i < ew-1; i++)
  594.       {
  595.     Move(rp,((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-1,y+EG_YOFFSET);
  596.     Draw(rp,((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-1,y+h-EG_YOFFSET-2);
  597.       }
  598.     }
  599.     if (chr->chr_Data)
  600.     {
  601.       for (i = 0; i < ew; i++)
  602.       {
  603.     for (j = 0; j < eh; j++)
  604.     {
  605.       SetAPen(rp,(*(chr->chr_Data+((j+egd->eg_YOffset)*chr->chr_Width)+
  606.         i+egd->eg_XOffset) != 0) ? pen2 : pen3);
  607.       RectFill(rp,(i*egd->eg_PixelX)+x+EG_XOFFSET,
  608.         (j*egd->eg_PixelY)+y+EG_YOFFSET,
  609.         ((i+1)*egd->eg_PixelX)+x+EG_XOFFSET-p,
  610.         ((j+1)*egd->eg_PixelY)+y+EG_YOFFSET-p);
  611.     }
  612.       }
  613.     }
  614.     if (egd->eg_ShowBaseline)
  615.     {
  616.       if (egd->eg_Baseline-egd->eg_YOffset < eh)
  617.       {
  618.     SetAPen(rp,dri->dri_Pens[SHINEPEN]);
  619.     Move(rp,x+EG_XOFFSET,((egd->eg_Baseline-egd->eg_YOffset+1)*
  620.       egd->eg_PixelY)+y+EG_YOFFSET-1);
  621.     Draw(rp,x+w-EG_XOFFSET-1,((egd->eg_Baseline-egd->eg_YOffset+1)*
  622.       egd->eg_PixelY)+y+EG_YOFFSET-1);
  623.       }
  624.     }
  625.   }
  626.   return 0;
  627. }
  628.  
  629. ULONG EditGadg_GET(Class *cl,Object *o,struct opGet *opg)
  630. {
  631. struct EditGadgData *egd = INST_DATA(cl,o);
  632. ULONG retval = TRUE;
  633. UWORD ew,eh;
  634.  
  635.   switch (opg->opg_AttrID)
  636.   {
  637.     case EG_Width:
  638.       EditGadg_GetSize(egd,((struct Gadget *)o)->Width,
  639.     ((struct Gadget *)o)->Height,&ew,&eh);
  640.       *(opg->opg_Storage) = ew;
  641.       break;
  642.     case EG_Height:
  643.       EditGadg_GetSize(egd,((struct Gadget *)o)->Width,
  644.     ((struct Gadget *)o)->Height,&ew,&eh);
  645.       *(opg->opg_Storage) = eh;
  646.       break;
  647.     case EG_XOffset:
  648.       *(opg->opg_Storage) = egd->eg_XOffset;
  649.       break;
  650.     case EG_YOffset:
  651.       *(opg->opg_Storage) = egd->eg_YOffset;
  652.       break;
  653.     case EG_PixelX:
  654.       *(opg->opg_Storage) = egd->eg_PixelX;
  655.       break;
  656.     case EG_PixelY:
  657.       *(opg->opg_Storage) = egd->eg_PixelY;
  658.       break;
  659.     default:
  660.       retval = DoSuperMethodA(cl,o,(Msg)opg);
  661.       break;
  662.   }
  663.   return retval;
  664. }
  665.  
  666. ULONG EditGadg_SET(Class *cl,struct Gadget *gadg,struct opSet *ops)
  667. {
  668. struct TagItem *tags, *tag;
  669. ULONG retval,pos;
  670. UWORD ew,eh;
  671. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  672.  
  673.   retval = DoSuperMethodA(cl,(Object *)gadg,(Msg)ops);
  674.   EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  675.   tags = ops->ops_AttrList;
  676.   if (tags)
  677.   {
  678.     if (tag = FindTagItem(EG_Baseline,tags))
  679.       egd->eg_Baseline = tag->ti_Data;
  680.     if (tag = FindTagItem(EG_CharNode,tags))
  681.       egd->eg_Node = (struct CharNode *)(tag->ti_Data);
  682.     if (tag = FindTagItem(EG_CharStruct,tags))
  683.       egd->eg_Char = (struct Character *)(tag->ti_Data);
  684.     if (tag = FindTagItem(EG_PixelX,tags))
  685.       egd->eg_PixelX = tag->ti_Data;
  686.     if (tag = FindTagItem(EG_PixelY,tags))
  687.       egd->eg_PixelY = tag->ti_Data;
  688.     if (tag = FindTagItem(EG_Update,tags))
  689.     {
  690.       switch (tag->ti_Data)
  691.       {
  692.     case GADG_HORIZ:
  693.       if (egd->eg_Node)
  694.       {
  695.         GetAttr(PGA_Top,egd->eg_Node->chln_HorizGadg,&pos);
  696.         if (egd->eg_XOffset != pos)
  697.         {
  698.           egd->eg_XOffset = pos;
  699.           EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  700.         }
  701.       }
  702.       break;
  703.     case GADG_VERT:
  704.       if (egd->eg_Node)
  705.       {
  706.         GetAttr(PGA_Top,egd->eg_Node->chln_VertGadg,&pos);
  707.         if (egd->eg_YOffset != pos)
  708.         {
  709.           egd->eg_YOffset = pos;
  710.           EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  711.         }
  712.       }
  713.       break;
  714.     case GADG_LEFT:
  715.       if (egd->eg_XOffset > 0)
  716.       {
  717.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  718.         {
  719.           egd->eg_XOffset--;
  720.           EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  721.           SetGadgetAttrs((struct Gadget *)egd->eg_Node->chln_HorizGadg,
  722.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_XOffset,
  723.         TAG_DONE);
  724.         }
  725.       }
  726.       break;
  727.     case GADG_RIGHT:
  728.       if (egd->eg_XOffset + ew < egd->eg_Char->chr_Width)
  729.       {
  730.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  731.         {
  732.           egd->eg_XOffset++;
  733.           EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  734.           SetGadgetAttrs((struct Gadget *)egd->eg_Node->chln_HorizGadg,
  735.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_XOffset,
  736.         TAG_DONE);
  737.         }
  738.       }
  739.       break;
  740.     case GADG_UP:
  741.       if (egd->eg_YOffset > 0)
  742.       {
  743.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  744.         {
  745.           egd->eg_YOffset--;
  746.           EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  747.           SetGadgetAttrs((struct Gadget *)egd->eg_Node->chln_VertGadg,
  748.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_YOffset,
  749.         TAG_DONE);
  750.         }
  751.       }
  752.       break;
  753.     case GADG_DOWN:
  754.       if (egd->eg_YOffset + eh < egd->eg_Char->chr_Height)
  755.       {
  756.         if ((egd->eg_Button = 1-egd->eg_Button) == 0)
  757.         {
  758.           egd->eg_YOffset++;
  759.           EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  760.           SetGadgetAttrs((struct Gadget *)egd->eg_Node->chln_VertGadg,
  761.         egd->eg_Node->chln_Window,NULL,PGA_Top,egd->eg_YOffset,
  762.         TAG_DONE);
  763.         }
  764.       }
  765.       break;
  766.     case GADG_NONE:
  767.       egd->eg_XOffset = 0;
  768.       egd->eg_YOffset = 0;
  769.       EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_REDRAW);
  770.       break;
  771.       }
  772.     }
  773.     if (tag = FindTagItem(EG_XOffset,tags))
  774.     {
  775.       if (egd->eg_XOffset != tag->ti_Data)
  776.       {
  777.     egd->eg_XOffset = tag->ti_Data;
  778.     EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  779.       }
  780.     }
  781.     if (tag = FindTagItem(EG_YOffset,tags))
  782.     {
  783.       if (egd->eg_YOffset != tag->ti_Data)
  784.       {
  785.     egd->eg_YOffset = tag->ti_Data;
  786.     EditGadg_Draw((Object *)gadg,ops->ops_GInfo,GREDRAW_UPDATE);
  787.       }
  788.     }
  789.   }
  790.   return retval;
  791. }
  792.  
  793. ULONG EditGadg_GOACTIVE(Class *cl,struct Gadget *gadg,struct gpInput *gpi)
  794. {
  795. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  796. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  797. WORD i,j;
  798. UWORD ew,eh;
  799.  
  800.   DoSuperMethodA(cl,(Object *)gadg,(Msg)gpi);
  801.   EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  802.   i = (gpi->gpi_Mouse.X - EG_XOFFSET) / egd->eg_PixelX;
  803.   j = (gpi->gpi_Mouse.Y - EG_YOFFSET) / egd->eg_PixelY;
  804.   if ((i >= 0) && (i < ew) && (j >= 0) && (j < eh))
  805.   {
  806.     EditGadg_TogglePixel(gadg,gpi,egd,i,j,TRUE);
  807.     return GMR_MEACTIVE;
  808.   }
  809.   else return GMR_NOREUSE;
  810. }
  811.  
  812. ULONG EditGadg_HANDLEINPUT(Class *cl,struct Gadget *gadg,
  813.   struct gpInput *gpi)
  814. {
  815. struct GadgetInfo *gi = gpi->gpi_GInfo;
  816. struct InputEvent *ie = gpi->gpi_IEvent;
  817. struct EditGadgData *egd = INST_DATA(cl,(Object *)gadg);
  818. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  819. ULONG retval = GMR_MEACTIVE;
  820. WORD i,j;
  821. UWORD ew,eh;
  822.  
  823.   if (gi->gi_Window)
  824.   {
  825.     if ((gi->gi_Window->Flags & WFLG_WINDOWACTIVE) == 0) return GMR_NOREUSE;
  826.   }
  827.   while (ie && (retval == GMR_MEACTIVE))
  828.   {
  829.     if (ie->ie_Class == IECLASS_RAWMOUSE)
  830.     {
  831.       if (ie->ie_Code != SELECTUP)
  832.       {
  833.     EditGadg_GetSize(egd,gadg->Width,gadg->Height,&ew,&eh);
  834.     i = (gpi->gpi_Mouse.X - EG_XOFFSET) / egd->eg_PixelX;
  835.     j = (gpi->gpi_Mouse.Y - EG_YOFFSET) / egd->eg_PixelY;
  836.     if ((i >= 0) && (i < ew) && (j >= 0) && (j < eh))
  837.     {
  838.       if ((i != egd->eg_ActiveX) || (j != egd->eg_ActiveY))
  839.         EditGadg_TogglePixel(gadg,gpi,egd,i,j,FALSE);
  840.     }
  841.     else retval = GMR_NOREUSE;
  842.       }
  843.       else retval = GMR_NOREUSE;
  844.     }
  845.     ie = ie->ie_NextEvent;
  846.   }
  847.   return retval;
  848. }
  849.  
  850. void EditGadg_TogglePixel(struct Gadget *gadg,struct gpInput *gpi,
  851.   struct EditGadgData *egd,WORD i,WORD j,BOOL first)
  852. {
  853. struct DrawInfo *dri = gpi->gpi_GInfo->gi_DrInfo;
  854. struct RastPort *rp;
  855. struct Character *chr;
  856. UBYTE *pixel;
  857. UBYTE pen1,pen2;
  858. UWORD px,py;
  859.  
  860.   egd->eg_ActiveX = i;
  861.   egd->eg_ActiveY = j;
  862.   if ((chr = egd->eg_Char) == NULL) return;
  863.   if (chr->chr_Data == NULL)
  864.   {
  865.     if ((chr->chr_Data = AllocVec(chr->chr_Width*chr->chr_Height,
  866.       MEMF_CLEAR)) == NULL) return;
  867.   }
  868.   pixel =
  869.     chr->chr_Data+((j+egd->eg_YOffset)*chr->chr_Width)+i+egd->eg_XOffset;
  870.   if (rp = ObtainGIRPort(gpi->gpi_GInfo))
  871.   {
  872.     pen1 = dri->dri_Pens[SHADOWPEN];
  873.     pen2 = dri->dri_Pens[BACKGROUNDPEN];
  874.     if (egd->eg_PixelBorder == 0)
  875.     {
  876.       px = 1;
  877.       py = 1;
  878.       if (egd->eg_ShowBaseline)
  879.     if (j+egd->eg_YOffset == egd->eg_Baseline) py++;
  880.     }
  881.     else
  882.     {
  883.       px = 2;
  884.       py = 2;
  885.     }
  886.     SetAfPt(rp,NULL,0);
  887.     if (first) egd->eg_FirstPixelState = 1-(*pixel);
  888.     *pixel = egd->eg_Toggle ? 1-(*pixel) : egd->eg_FirstPixelState;
  889.     SetAPen(rp,*pixel == 1 ? pen1 : pen2);
  890.     RectFill(rp,(i*egd->eg_PixelX)+gadg->LeftEdge+EG_XOFFSET,
  891.       (j*egd->eg_PixelY)+gadg->TopEdge+EG_YOFFSET,
  892.       ((i+1)*egd->eg_PixelX)+gadg->LeftEdge+EG_XOFFSET-px,
  893.       ((j+1)*egd->eg_PixelY)+gadg->TopEdge+EG_YOFFSET-py);
  894.     ReleaseGIRPort(rp);
  895.     *(egd->eg_ChangePtr) = TRUE;
  896.   }
  897. }
  898.  
  899. /* slider gadget subClass */
  900.  
  901. struct SlideGadgData
  902. {
  903.   ULONG sg_Total,sg_Visible;
  904. };
  905.  
  906. __geta4 ULONG DispatchSlideGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg);
  907. ULONG SlideGadg_NOTIFY(Class *cl,Object *o,struct opUpdate *opu);
  908. ULONG SlideGadg_NEW(Class *cl,Object *o,struct opSet *ops);
  909. ULONG SlideGadg_SET(Class *cl,Object *o,struct opSet *ops);
  910.  
  911. Class *InitSlideGadgClass(void)
  912. {
  913. Class *super, *cl = NULL;
  914.  
  915.   if (super = BGUI_GetClassPtr(BGUI_PROP_GADGET))
  916.   {
  917.     cl = MakeClass(NULL,NULL,super,0,0);
  918.     if (cl) cl->cl_Dispatcher.h_Entry = (HOOKFUNC)DispatchSlideGadg;
  919.   }
  920.   return cl;
  921. }
  922.  
  923. BOOL FreeSlideGadgClass(Class *cl)
  924. {
  925.   return FreeClass(cl);
  926. }
  927.  
  928. __geta4 ULONG DispatchSlideGadg(__a0 Class *cl,__a2 Object *o,__a1 Msg msg)
  929. {
  930. ULONG retval;
  931.  
  932.   switch (msg->MethodID)
  933.   {
  934.     case OM_NEW:
  935.       retval = SlideGadg_NEW(cl,o,(struct opSet *)msg);
  936.       break;
  937.     case OM_SET:
  938.     case OM_UPDATE:
  939.       retval = SlideGadg_SET(cl,o,(struct opSet *)msg);
  940.       break;
  941.     case OM_NOTIFY:
  942.       retval = SlideGadg_NOTIFY(cl,o,(struct opUpdate *)msg);
  943.       break;
  944.     default:
  945.       retval = DoSuperMethodA(cl,o,(Msg)msg);
  946.       break;
  947.   }
  948.   return retval;
  949. }
  950.  
  951. ULONG SlideGadg_NEW(Class *cl,Object *o,struct opSet *ops)
  952. {
  953. ULONG retval = 0;
  954. struct SlideGadgData *sgd;
  955.  
  956.   retval = (ULONG)DoSuperMethodA(cl,o,(Msg)ops);
  957.   if (retval)
  958.   {
  959.     sgd = INST_DATA(cl,retval);
  960.     sgd->sg_Total = GetTagData(PGA_Total,0,ops->ops_AttrList);
  961.     sgd->sg_Visible = GetTagData(PGA_Visible,0,ops->ops_AttrList);
  962.   }
  963.   return retval;
  964. }
  965.  
  966. ULONG SlideGadg_SET(Class *cl,Object *o,struct opSet *ops)
  967. {
  968. struct SlideGadgData *sgd = INST_DATA(cl,o);
  969. struct GadgetInfo *gi = ops->ops_GInfo;
  970. struct TagItem *tags, *tag;
  971. struct TagItem inactive;
  972. ULONG retval;
  973.  
  974.   retval = DoSuperMethodA(cl,o,(Msg)ops);
  975.   tags = ops->ops_AttrList;
  976.   if (tags)
  977.   {
  978.     if (tag = FindTagItem(PGA_Total,tags)) sgd->sg_Total = tag->ti_Data;
  979.     if (tag = FindTagItem(PGA_Visible,tags)) sgd->sg_Visible = tag->ti_Data;
  980.     Gadg_SetTag(&inactive,TAG_DONE,0);
  981.     DoMethod(o,OM_NOTIFY,&inactive,gi,0);
  982.   }
  983.   return retval;
  984. }
  985.  
  986. ULONG SlideGadg_NOTIFY(Class *cl,Object *o,struct opUpdate *opu)
  987. {
  988. struct SlideGadgData *sgd = INST_DATA(cl,o);
  989. struct TagItem tags[3];
  990. ULONG pos = 0;
  991.  
  992.   GetAttr(PGA_Top,o,&pos);
  993.   Gadg_SetTag(&tags[0],GA_ID,((struct Gadget *)o)->GadgetID);
  994.   Gadg_SetTag(&tags[1],SCRL_Right,sgd->sg_Total-sgd->sg_Visible-pos);
  995.   if (opu->opu_AttrList == NULL)
  996.     Gadg_SetTag(&tags[2],TAG_DONE,0);
  997.   else
  998.     Gadg_SetTag(&tags[2],TAG_MORE,(ULONG)opu->opu_AttrList);
  999.   return DoSuperMethod(cl,o,OM_NOTIFY,tags,opu->opu_GInfo,opu->opu_Flags);
  1000. }
  1001.  
  1002. /* This is a listview subclass used for preferences. It is an adapted
  1003.    version of one of Jan's BGUI demos. */
  1004.  
  1005. typedef struct
  1006. {
  1007.   Object *fld_Accept;
  1008.   BOOL fld_SortDrops;
  1009. } FLD;
  1010.  
  1011. #define SET(x)     ((struct opSet *)x)
  1012. #define QUERY(x) ((struct bmDragPoint *)x)
  1013. #define DROP(x)     ((struct bmDropped *)x)
  1014.  
  1015. SetFLAttr(FLD *fld,struct TagItem *attr)
  1016. {
  1017. struct TagItem *tag,*tstate = attr;
  1018.  
  1019.   while (tag = NextTagItem(&tstate))
  1020.   {
  1021.     switch (tag->ti_Tag)
  1022.     {
  1023.       case FL_AcceptDrop:
  1024.     fld->fld_Accept = (Object *)tag->ti_Data;
  1025.     break;
  1026.       case FL_SortDrops:
  1027.     fld->fld_SortDrops = tag->ti_Data;
  1028.     break;
  1029.     }
  1030.   }
  1031. }
  1032.  
  1033. __geta4 ULONG DispatchFL(__a0 Class *cl,__a2 Object *obj,__a1 Msg msg)
  1034. {
  1035. FLD *fld;
  1036. APTR entry;
  1037. struct IBox *ib;
  1038. ULONG rc,spot;
  1039.  
  1040.   switch (msg->MethodID)
  1041.   {
  1042.     case OM_NEW:
  1043.       if (rc = DoSuperMethodA(cl,obj,msg))
  1044.       {
  1045.     fld = (FLD *)INST_DATA(cl,rc);
  1046.     fld->fld_Accept = NULL;
  1047.     fld->fld_SortDrops = FALSE;
  1048.     SetFLAttr(fld,SET(msg)->ops_AttrList);
  1049.       }
  1050.       break;
  1051.     case OM_SET:
  1052.       rc = DoSuperMethodA(cl,obj,msg);
  1053.       fld = (FLD *)INST_DATA(cl,obj);
  1054.       SetFLAttr(fld,SET(msg)->ops_AttrList);
  1055.       break;
  1056.     case BASE_DRAGQUERY:
  1057.       if (QUERY(msg)->bmdp_Source == obj) return DoSuperMethodA(cl,obj,msg);
  1058.  
  1059.       fld = (FLD *)INST_DATA(cl,obj);
  1060.       if (QUERY(msg)->bmdp_Source == fld->fld_Accept)
  1061.       {
  1062.     GetAttr(LISTV_ViewBounds,obj,(ULONG *)&ib);
  1063.     if (QUERY(msg)->bmdp_Mouse.X < ib->Width) return BQR_ACCEPT;
  1064.       }
  1065.       rc = BQR_REJECT;
  1066.       break;
  1067.     case BASE_DROPPED:
  1068.       if (DROP(msg)->bmd_Source == obj) return DoSuperMethodA(cl,obj,msg);
  1069.  
  1070.       fld = (FLD *)INST_DATA(cl,obj);
  1071.       GetAttr( LISTV_DropSpot,obj,&spot);
  1072.       while (entry = (APTR)FirstSelected(DROP(msg)->bmd_Source))
  1073.       {
  1074.     if (fld->fld_SortDrops == FALSE)
  1075.       DoMethod(obj,LVM_INSERTSINGLE,NULL,spot,entry,LVASF_SELECT);
  1076.     else
  1077.       DoMethod(obj,LVM_ADDSINGLE,NULL,entry,LVAP_SORTED,LVASF_SELECT);
  1078.     DoMethod(DROP(msg)->bmd_Source,LVM_REMENTRY,NULL,entry);
  1079.       }
  1080.       BGUI_DoGadgetMethod(DROP(msg)->bmd_Source,
  1081.     DROP(msg)->bmd_SourceWin,
  1082.     DROP(msg)->bmd_SourceReq,
  1083.     LVM_REFRESH,NULL);
  1084.       rc = 1;
  1085.       break;
  1086.     default:
  1087.       rc = DoSuperMethodA(cl,obj,msg);
  1088.       break;
  1089.   }
  1090.   return rc;
  1091. }
  1092.  
  1093. Class *InitFLClass(void)
  1094. {
  1095. Class *super,*cl = NULL;
  1096.  
  1097.   if (super = BGUI_GetClassPtr(BGUI_LISTVIEW_GADGET))
  1098.   {
  1099.     if (cl = MakeClass(NULL,NULL,super,sizeof(FLD),0L))
  1100.       cl->cl_Dispatcher.h_Entry = (HOOKFUNC)DispatchFL;
  1101.   }
  1102.   return cl;
  1103. }
  1104.  
  1105. BOOL FreeFLClass(Class *cl)
  1106. {
  1107.   return FreeClass(cl);
  1108. }
  1109.